using System.Collections;
using System.Collections.Generic;
using ECS.Tutorial01;
using Tutorial1_Spawner;
using Tutorial2_SinMove;
using Unity.Burst;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Mathematics.Geometry;
using Unity.Transforms;
using UnityEngine;

[BurstCompile]
public partial struct SpawnerSystem : ISystem
{
    private int _count;
    public void OnCreate(ref SystemState state)
    {
        state.RequireForUpdate<BeginSimulationEntityCommandBufferSystem.Singleton>();
        Debug.Log("SpawnerSystem OnCreate");
    }

    public void OnDestroy(ref SystemState state)
    {
        Debug.Log("SpawnerSystem OnDestroy");
    }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        EntityCommandBuffer.ParallelWriter ecb = GetECB(ref state);
        var job = new ProcessSpawnerJob()
        {
            ECB = ecb,
            ElapsedTime = SystemAPI.Time.ElapsedTime
        };
        job.ScheduleParallel();
    }

    private EntityCommandBuffer.ParallelWriter GetECB(ref SystemState state)
    {
        var ecbSingleton = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>();
        var ecb = ecbSingleton.CreateCommandBuffer(state.WorldUnmanaged);
        return ecb.AsParallelWriter();
    }
}

[BurstCompile]
public partial struct ProcessSpawnerJob : IJobEntity
{
    public EntityCommandBuffer.ParallelWriter ECB;
    public double ElapsedTime;
    
    private void Execute([ChunkIndexInQuery] int chunkIndex, ref Spawner spawner)
    {
        if (spawner.Count >= 10000)
        {
            return;
        }
        
        
        if (spawner.NextSpawnTime < ElapsedTime)
        {
            var newEntity = ECB.Instantiate(chunkIndex, spawner.Prefab);
            ECB.SetComponent(chunkIndex, newEntity, LocalTransform.FromPosition(spawner.SpawnPosition));
            ECB.AddComponent(chunkIndex, newEntity, new CubeTag());
            
            spawner.NextSpawnTime = (float)ElapsedTime + spawner.SpawnRate;
            spawner.Count++;
            int x = spawner.Count % 100;
            x = x < 50 ? -x : x - 50;
            spawner.SpawnPosition = new float3(x, 0, math.floor(spawner.Count / 100f));
        }
    }
}
